package ciyuan.Structure.MyFile;

import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.INBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.storage.WorldSavedData;
import net.minecraftforge.common.util.ITeleporter;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.function.Function;

/**
 * @author 150149
 */
public class FBStructureManager extends WorldSavedData  {

    private static final String WORLD_SAVE_DATA_NAME = "CY_Structure";
    private final static String CY_FB = "cyfb";
    private final static String CY_FB_ID = "cyfbid";
    private final static String CY_FB_NAME = "cyfbname";
    private final static String CY_FB_REFRESHTIME = "cyfbrefreshtime";
    private final static String CY_FB_START_X = "cyfbstartx";
    private final static String CY_FB_START_Y = "cyfbstarty";
    private final static String CY_FB_START_Z = "cyfbstartz";
    private final static String CY_FB_BUILD_X = "cyfbbuildx";
    private final static String CY_FB_BUILD_Y = "cyfbbuildy";
    private final static String CY_FB_BUILD_Z = "cyfbbuildz";
    private final static String CY_FB_LASTX = "cyfblastx";
    private final static String CY_FB_LASTZ = "cyfblastz";
    private final static String CY_FB_LASTID = "cyfblastid";
    private static final Vector<MyFB> fbList = new Vector<>();
    private static final List<MyFB> fbType = new ArrayList<>();

    public static final long MAX_REFRESHTIME = 60 * 60 * 1000;

    public static int lastX = -30000;
    public static int lastZ = -30000;
    public static int lastID = -1;

    public FBStructureManager() {
        super(WORLD_SAVE_DATA_NAME);
    }

    @Override
    public void load(CompoundNBT nbt) {
        ListNBT cyfb = (ListNBT) nbt.get(CY_FB);
        if (cyfb!=null) {
            for (INBT inbt:cyfb) {
                CompoundNBT compoundNBT = (CompoundNBT) inbt;
                int id = compoundNBT.getInt(CY_FB_ID);
                String name = compoundNBT.getString(CY_FB_NAME);
                long refreshTime = compoundNBT.getLong(CY_FB_REFRESHTIME);
                int sx = compoundNBT.getInt(CY_FB_START_X);
                int sy = compoundNBT.getInt(CY_FB_START_Y);
                int sz = compoundNBT.getInt(CY_FB_START_Z);

                int bx = compoundNBT.getInt(CY_FB_BUILD_X);
                int by = compoundNBT.getInt(CY_FB_BUILD_Y);
                int bz = compoundNBT.getInt(CY_FB_BUILD_Z);

                MyFB myFB = new MyFB(new BlockPos(sx,sy,sz),new BlockPos(bx,by,bz),null,id,name,refreshTime);
                fbList.add(myFB);
            }
            lastX = nbt.getInt(CY_FB_LASTX);
            lastZ = nbt.getInt(CY_FB_LASTZ);
            lastID = nbt.getInt(CY_FB_LASTID);
        }
    }

    @Override
    public CompoundNBT save(CompoundNBT nbt) {
        ListNBT cyfb = new ListNBT();
        for (MyFB myFB:fbList) {
            CompoundNBT compoundNBT = new CompoundNBT();
            compoundNBT.putInt(CY_FB_ID,myFB.getId());
            compoundNBT.putString(CY_FB_NAME, myFB.getName());
            compoundNBT.putLong(CY_FB_REFRESHTIME,myFB.getRefreshTime());
            compoundNBT.putInt(CY_FB_START_X,myFB.getStartPos().getX());
            compoundNBT.putInt(CY_FB_START_Y,myFB.getStartPos().getY());
            compoundNBT.putInt(CY_FB_START_Z,myFB.getStartPos().getZ());

            compoundNBT.putInt(CY_FB_BUILD_X,myFB.getBuildPos().getX());
            compoundNBT.putInt(CY_FB_BUILD_Y,myFB.getBuildPos().getY());
            compoundNBT.putInt(CY_FB_BUILD_Z,myFB.getBuildPos().getZ());
            cyfb.add(compoundNBT);
        }
        nbt.putInt(CY_FB_LASTX,lastX);
        nbt.putInt(CY_FB_LASTZ,lastZ);
        nbt.putInt(CY_FB_LASTID,lastID);
        nbt.put(CY_FB,cyfb);
        return nbt;
    }

    private BlockPos getPlaceBlockPos() {
        int tempx = lastX;
        int tempz = lastZ;
        if (lastX>=30000) {
            lastX = -30000;
            lastZ = lastZ + 500;
        }
        return new BlockPos(tempx,100,tempz);
    }

    private int getNextID() {
        return ++lastID;
    }

    private void teleport(PlayerEntity entity, ServerWorld destination, BlockPos pos) {
        entity.changeDimension(destination, new ITeleporter() {
            @Override
            public Entity placeEntity(Entity entity, ServerWorld currentWorld, ServerWorld destWorld, float yaw, Function<Boolean, Entity> repositionEntity) {
                entity = repositionEntity.apply(false);
                entity.teleportTo(pos.getX(), pos.getY(), pos.getZ());
                return entity;
            }
        });
    }

    private static List<BlockInfo> readFile(File file)
    {
        List<BlockInfo> blockInfoList = new ArrayList<>();
        if(file.isFile() && file.exists()){
            try {
                FileInputStream fileInputStream = new FileInputStream(file);
                InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

                String text = null;
                while((text = bufferedReader.readLine()) != null){
                    if ("".equals(text)) {
                        continue;
                    }
                    String[] strs = text.split(",");
                    BlockPos blockPos = new BlockPos(Integer.parseInt(strs[0]),Integer.parseInt(strs[1]),Integer.parseInt(strs[2]));
                    BlockInfo blockInfo = new BlockInfo(blockPos,strs[3]);
                    blockInfoList.add(blockInfo);
                }
                bufferedReader.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return blockInfoList;
    }

    public static void writeFile(File file,List<BlockInfo> blockInfoList){
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(file));
            for (BlockInfo blockInfo:blockInfoList) {
                BlockPos blockPos = blockInfo.blockPos;
                String name = blockInfo.blockState.getBlock().getDescriptionId();
                bw.write("" + blockPos.getX() + "," + blockPos.getY() + "," + blockPos.getZ() + "," + name);
                bw.newLine();
            }
            bw.flush();
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
